﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LDCRNewEdit.Model;
using LDCRNewEdit.Services;
using LDCRNewEdit.Utils;

namespace LDCRNewEdit.UI.地图编辑.场景地图设计
{
    public partial class SceneMapEdit : Form
    {
        private string mapFilename = string.Empty;
        private SceneMap sceneMap = null;

        private int XScale = 24;        //格子半高
        private int YScale = 12;        //格子半宽
        private bool ShowGrid = true;   //是否显示网格
        private bool ShowBlock = true;     //是否显示障碍点
        private bool EditBlock = false;     //编辑障碍点状态
        private bool ShowBuidBorder = true; //是否显示建筑边框

        private bool IsClickDown = false;
        private int ScrollX = 0;
        private int ScrollY = 0;
        private bool IsChangeMap = true;

        private SceneBuildLv openLevel; //打开的建筑对象
        private SceneBuildLv selectLevel;   //选中的对象
        private SceneBuildLv copyLevel; //被复制的对象

        private Point mouseClickPoint;

        public SceneMapEdit()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Resources.GetPath("SceneGround");
            ofd.Title = "请先选择一个地面文件";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {

                sceneMap = new SceneMap();
                mapFilename = null;

                this.textBoxGroundPath.Text = ofd.FileName.Replace(Resources.GamePath, "");

                sceneMap.GroundPath = this.textBoxGroundPath.Text;

                //读取地面文件
                int[] result = LoadGroundPath(ofd.FileName);
                sceneMap.MapWidth = (short)(result[0] / XScale);
                sceneMap.MapHeight = sceneMap.MapWidth;
                sceneMap.MaxWidth = (short)result[0];
                sceneMap.MaxHeight = (short)result[1];
                sceneMap.XOff = (short)(result[0] / 2);
                sceneMap.YOff = (short)(result[1] / 3);


                this.textBoxW.Text = sceneMap.MapWidth.ToString();
                this.textBoxH.Text = sceneMap.MapHeight.ToString();
                this.textBoxMW.Text = sceneMap.MaxWidth.ToString();
                this.textBoxMH.Text = sceneMap.MaxHeight.ToString();
                this.textBoxXOFF.Text = sceneMap.XOff.ToString(); ;
                this.textBoxYOFF.Text = sceneMap.YOff.ToString();

                

                selectLevel = null;

                IsChangeMap = true;
                UpdatePictureBox();
            }

        }

        private void SceneMapEdit_Load(object sender, EventArgs e)
        {
            this.MouseWheel += new MouseEventHandler(PictureBox_MouseWheel);
        }

        void PictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            ScrollY -= e.Delta;
            if (ScrollY < 0) ScrollY = 0;
            if (ScrollY > this.panel2.VerticalScroll.Maximum) ScrollY = this.panel2.VerticalScroll.Maximum;
            this.panel2.VerticalScroll.Value = ScrollY;
            UpdatePictureBox();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Resources.GetPath("SceneMap");
            ofd.Filter = "*.smap|*.smap";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                mapFilename = ofd.FileName;

                //读取文件
                sceneMap = SceneMapService.LoadSceneMap(mapFilename);
                this.textBoxSceneName.Text = sceneMap.Name;
                this.textBoxGroundPath.Text = sceneMap.GroundPath;
                this.textBoxW.Text = sceneMap.MapWidth.ToString();
                this.textBoxH.Text = sceneMap.MapHeight.ToString();
                this.textBoxMW.Text = sceneMap.MaxWidth.ToString();
                this.textBoxMH.Text = sceneMap.MaxHeight.ToString();
                this.textBoxXOFF.Text = sceneMap.XOff.ToString(); ;
                this.textBoxYOFF.Text = sceneMap.YOff.ToString();

                //加载地面文件
                sceneMap.GroundList.AddRange(SceneMapService.LoadGroundMap(Resources.GamePath + sceneMap.GroundPath));


                IsChangeMap = true;
                UpdatePictureBox();

            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (sceneMap == null)
            {
                MessageBox.Show("请先打开或新建一个场景!");
                return;
            }

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Resources.GetPath("SceneGround");
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {

                //读取地面文件
                int[] result = LoadGroundPath(ofd.FileName);
                this.textBoxMW.Text = result[0].ToString();
                this.textBoxMH.Text = result[1].ToString();


                this.textBoxGroundPath.Text = ofd.FileName.Replace(Resources.GamePath, "");
            }
        }

        /// <summary>
        /// 加载地面文件，返回MX和MY
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private int[] LoadGroundPath(string filename)
        {
            List<SceneGroundLv> list = SceneMapService.LoadGroundMap(filename);

            sceneMap.GroundList.Clear();
            sceneMap.GroundList.AddRange(list);

            int mx = 0;
            int my = 0;

            foreach (SceneGroundLv sg in list)
            {
                if (sg.X + sg.Image.Width > mx)
                {
                    mx = sg.X + sg.Image.Width;
                }
                if (sg.Y + sg.Image.Height > my)
                {
                    my = sg.Y + sg.Image.Height;
                }
            }

            return new int[] { mx, my };


        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (sceneMap == null)
            {
                MessageBox.Show("请先打开或新建一个场景再进行保存!");
                return;
            }

            try
            {
                sceneMap.Name = textBoxSceneName.Text.Trim();

                sceneMap.MapWidth = short.Parse(textBoxW.Text);
                sceneMap.MapHeight = short.Parse(textBoxH.Text);
                sceneMap.MaxWidth = short.Parse(textBoxMW.Text);
                sceneMap.MaxHeight = short.Parse(textBoxMH.Text);
                sceneMap.XOff = short.Parse(textBoxXOFF.Text);
                sceneMap.YOff = short.Parse(textBoxYOFF.Text);

                if (string.IsNullOrEmpty(mapFilename))
                {
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.InitialDirectory = Resources.GetPath("SceneMap");
                    sfd.Filter = "*.smap|*.smap";
                    sfd.FileName = sceneMap.Name+".smap";

                    if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        mapFilename = sfd.FileName;

                        SceneMapService.SaveSceneMap(mapFilename, sceneMap);
                    }
                    else
                    {
                        return;
                    }

                }
                else
                {
                    SceneMapService.SaveSceneMap(mapFilename, sceneMap);
                }

                MessageBox.Show("保存成功!");

                UpdatePictureBox(); 
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存失败!" + ex.Message);
            }
        }

        /// <summary>
        /// 更新贴图
        /// </summary>
        private void UpdatePictureBox()
        {
            if (sceneMap == null)
                return;

            int sh = Screen.PrimaryScreen.Bounds.Height;

            int sw = Screen.PrimaryScreen.Bounds.Width;

            Bitmap img = null;
            Graphics g = null;

            this.pictureBox1.Location = new Point(0, 0);
            if (IsChangeMap)
            {

                ScrollX = 0;
                ScrollY = 0;

                this.pictureBox1.Size = new Size(sceneMap.MapWidth * XScale * 2, sceneMap.MapHeight * YScale * 2);
                
                if (this.pictureBox1.Size.Width > sw)
                {
                    this.panel2.HorizontalScroll.Value = this.pictureBox1.Size.Width / 2;
                    ScrollX = this.pictureBox1.Size.Width / 2;
                }
                else
                {
                    this.panel2.HorizontalScroll.Value = 0;
                }

                if (this.pictureBox1.Size.Height > sh)
                {
                    this.panel2.VerticalScroll.Value = this.pictureBox1.Size.Height / 2;
                    ScrollY = this.pictureBox1.Size.Height / 2;
                }
                else
                {
                    this.panel2.VerticalScroll.Value = 0;
                }
                 
                IsChangeMap = false;
            }


            //img = new Bitmap(map.MapWidth * XScale * 2, map.MapHeight * YScale * 2);
            int w = sw;
            int h = sh;
            if (this.pictureBox1.Size.Width - ScrollX < w)
            {
                w = this.pictureBox1.Size.Width - ScrollX;
                if (w <= 0)
                {
                    return;
                }
            }
            if (this.pictureBox1.Size.Height - ScrollY < h)
            {
                h = this.pictureBox1.Size.Height - ScrollY;
                if (h <= 0)
                {
                    return;
                }
            }
            img = new Bitmap(w, h);
            if (this.pictureBox1.Image != null)
            {
                this.pictureBox1.Image.Dispose();
            }
            g = Graphics.FromImage(img);


            

            //显示地面
            foreach (SceneGroundLv sl in sceneMap.GroundList)
            {
                if (sl.X + sceneMap.XOff - ScrollX >= -sl.W && sl.X + sceneMap.XOff - ScrollX + sl.W <= w + sl.W && sl.Y + sceneMap.YOff - ScrollY >= -sl.H && sl.Y + sceneMap.YOff - ScrollY <= h + sl.H)
                    g.DrawImage(sl.Image, sl.X + sceneMap.XOff - ScrollX, sl.Y + sceneMap.YOff - ScrollY, sl.Image.Width, sl.Image.Height);
            }


            //建筑排序
            sceneMap.BuilList.Sort();
            foreach (SceneBuildLv sl in sceneMap.BuilList)
            {
                if (sl.X + sceneMap.XOff - ScrollX >= -sl.W && sl.X + sceneMap.XOff - ScrollX + sl.W <= w + sl.W && sl.Y + sceneMap.YOff - ScrollY >= -sl.H && sl.Y + sceneMap.YOff - ScrollY <= h + sl.H)
                {
                    g.DrawImage(sl.Image, sl.X + sceneMap.XOff - ScrollX, sl.Y + sceneMap.YOff - ScrollY, sl.Image.Width, sl.Image.Height);
                    if (ShowBuidBorder)
                    {
                        g.DrawRectangle(new Pen(Color.Green), sl.X + sceneMap.XOff - ScrollX, sl.Y + sceneMap.YOff - ScrollY, sl.Image.Width, sl.Image.Height);
                    }
                }
            }

            //选中的添加一个红框
            
            if (selectLevel != null)
            {
                g.DrawRectangle(new Pen(Color.Red), selectLevel.X + sceneMap.XOff - ScrollX, selectLevel.Y + sceneMap.YOff - ScrollY, selectLevel.Image.Width, selectLevel.Image.Height);
            }
            

            //刚打开的图片，半透明
            
            if (openLevel != null)
            {
                g.DrawImage(openLevel.Image, openLevel.X + sceneMap.XOff, openLevel.Y + sceneMap.YOff, openLevel.Image.Width, openLevel.Image.Height);
            }

            //显示障碍点
            if (ShowBlock)
            {
                SolidBrush brush = new SolidBrush(Color.FromArgb(96, Color.Red));
                foreach (Point p in sceneMap.BlockSet)
                {
                    g.FillPolygon(brush, convertXY(p).ToArray());
                }
            }

            //绘制网格

            if (ShowGrid)
            {
                Pen p = new Pen(Color.Cyan);

                for (int i = 0; i <= sceneMap.MapWidth; i++)
                {
                    g.DrawLine(p, new Point((sceneMap.MapWidth + i) * XScale - ScrollX, i * YScale - ScrollY), new Point(i * XScale - ScrollX, (sceneMap.MapHeight + i) * YScale - ScrollY));

                }

                for (int i = 0; i <= sceneMap.MapHeight; i++)
                {
                    g.DrawLine(p, new Point((sceneMap.MapWidth - i) * XScale - ScrollX, i * YScale - ScrollY), new Point(sceneMap.MapWidth * XScale * 2 - i * XScale - ScrollX, (sceneMap.MapHeight + i) * YScale - ScrollY));
                }
            }

            g.Dispose();

            pictureBox1.Image = img;

            pictureBox1.Update();
        }


        /// <summary>
        /// 像素转为XY坐标
        /// </summary>
        /// <param name="px"></param>
        /// <returns></returns>
        private Point convertPoint(int x, int y)
        {
            Point p = new Point();
            x += ScrollX;
            y += ScrollY;
            p.X = (int)(((double)(x - sceneMap.MapWidth * XScale) / XScale) + (double)(y)
                    / YScale) / 2;
            p.Y = (int)(((double)(y) / YScale - (double)(x - sceneMap.MapWidth * XScale)
                    / XScale)) / 2;

            return p;
        }

        /// <summary>
        /// 把XY坐标转为像素
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private List<Point> convertXY(Point p)
        {

            List<Point> list = new List<Point>();
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - p.Y) * XScale - ScrollX, (p.X + p.Y) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - 1 - p.Y) * XScale - ScrollX, (p.Y + 1 + p.X) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - p.Y) * XScale - ScrollX, (p.Y + 2 + p.X) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X + 1 - p.Y) * XScale - ScrollX, (p.Y + 1 + p.X) * YScale - ScrollY));

            return list;
        }

        private void panel2_Scroll(object sender, ScrollEventArgs e)
        {
            if (ScrollOrientation.HorizontalScroll == e.ScrollOrientation)
            {
                ScrollX = e.NewValue;
            }
            else
            {
                ScrollY = e.NewValue;
            }

            UpdatePictureBox();
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            sceneMap.MapWidth = short.Parse(textBoxW.Text);
            sceneMap.MapHeight = short.Parse(textBoxH.Text);
            sceneMap.MaxWidth = short.Parse(textBoxMW.Text);
            sceneMap.MaxHeight = short.Parse(textBoxMH.Text);
            sceneMap.XOff = short.Parse(textBoxXOFF.Text);
            sceneMap.YOff = short.Parse(textBoxYOFF.Text);

            UpdatePictureBox();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.ShowGrid = this.checkBox1.Checked;
            UpdatePictureBox();
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            //显示表格
            this.ShowBlock = this.checkBox3.Checked;
            UpdatePictureBox();
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            //编辑block状态
            EditBlock = this.checkBox2.Checked;

            this.checkBox3.Checked = true;
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (sceneMap == null)
                return;

            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                IsClickDown = true;

                //增加障碍点
                if (EditBlock)
                {
                    Point p = convertPoint(e.X, e.Y);
                    if (p.X >= 0 && p.Y >= 0 && p.X < sceneMap.MapWidth && p.Y < sceneMap.MapHeight)
                    {
                        sceneMap.BlockSet.Add(p);
                    }
                    
                }
                
                else
                {
                    openLevel = null;
                    //判断选中
                    for (int i = this.sceneMap.BuilList.Count - 1; i >= 0; i--)
                    {
                        SceneBuildLv sl = this.sceneMap.BuilList[i];
                        bool flag = false;
                        if (e.X - sceneMap.XOff + ScrollX >= sl.X && e.X - sceneMap.XOff + ScrollX <= sl.X + sl.Image.Width && e.Y - sceneMap.YOff + ScrollY >= sl.Y && e.Y - sceneMap.YOff + ScrollY <= sl.Y + sl.Image.Height)
                        {
                            selectLevel = sl;
                            flag = true;

                            mouseClickPoint.X = selectLevel.X-(e.X - sceneMap.XOff + ScrollX);
                            mouseClickPoint.Y = selectLevel.Y-(e.Y - sceneMap.YOff + ScrollY);


                            break;
                        }
                        if (!flag)
                        {
                            selectLevel = null;
                        }
                    }
                }
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (EditBlock)
                {
                    Point p = convertPoint(e.X, e.Y);
                    sceneMap.BlockSet.Remove(p);
                }
                
                else
                {
                    //放置刚打开的图片
                    if (openLevel != null)
                    {
                        openLevel.X += (short)(ScrollX);
                        openLevel.Y += (short)(ScrollY);
                        this.sceneMap.BuilList.Add(openLevel);
                        openLevel = null;

                    }
                    else
                    {
                        if (selectLevel != null)
                        {
                            this.查看ToolStripMenuItem.Enabled = true;
                            this.复制ToolStripMenuItem.Enabled = true;
                            this.删除ToolStripMenuItem.Enabled = true;
                        }
                        else
                        {
                            this.查看ToolStripMenuItem.Enabled = false;
                            this.复制ToolStripMenuItem.Enabled = false;
                            this.删除ToolStripMenuItem.Enabled = false;
                        }

                        this.粘贴ToolStripMenuItem.Enabled = (copyLevel != null);

                        this.contextMenuStrip1.Show((Control)sender,e.X, e.Y);
                    }

                    //取消选中
                    //selectLevel = null;

                    //隐藏选中输入框
                    //this.panel3.Visible = false;
                }
            }

            UpdatePictureBox();
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (sceneMap == null)
                return;

            //增加障碍点
            if (EditBlock && IsClickDown)
            {
                Point p = convertPoint(e.X, e.Y);
                if (p.X >= 0 && p.Y >= 0 && p.X < sceneMap.MapWidth && p.Y < sceneMap.MapHeight)
                {
                    if (sceneMap.BlockSet.Add(p))
                        UpdatePictureBox();
                }
            }
            else if (selectLevel != null && IsClickDown)
            {
                //要注意补上点中时的鼠标中间点
                selectLevel.X = (short)(e.X - sceneMap.XOff + ScrollX + mouseClickPoint.X);
                selectLevel.Y = (short)(e.Y - sceneMap.YOff + ScrollY + mouseClickPoint.Y);

                UpdatePictureBox();
            }
            else
            {

                if (openLevel != null)
                {
                    openLevel.X = (short)(e.X - sceneMap.XOff - openLevel.W/2);
                    openLevel.Y = (short)(e.Y - sceneMap.YOff - openLevel.H / 2);

                    UpdatePictureBox();
                }

                this.labelPosition.Text = string.Format("{0},{1}", e.X - sceneMap.XOff + ScrollX, e.Y - sceneMap.YOff + ScrollY);

                Point p = convertPoint(e.X, e.Y);
                this.labelGrid.Text = p.X + "," + p.Y;
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            IsClickDown = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "图片文件|*.png";
            ofd.InitialDirectory = Resources.GetPath("SceneBuildPath");
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string filename = ofd.FileName;
                if (!filename.StartsWith(Resources.GamePath))
                {
                    MessageBox.Show("只能选游戏资源目录下的文件哦!");
                    return;
                }

                openLevel = new SceneBuildLv();

                openLevel.FrameNum = 1;
                openLevel.Path = filename.Replace(Resources.GamePath,"");
                openLevel.Image = Image.FromFile(filename);
                openLevel.W = (short)openLevel.Image.Width;
                openLevel.H = (short)openLevel.Image.Height;
                openLevel.KeyPointX = (short)(openLevel.W / 2);
                openLevel.KeyPointY = openLevel.H;

                openLevel.Level = 2;
                

            }
        }

        private void 查看ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectLevel == null)
            {
                return;
            }

            SceneBuildViewForm form = new SceneBuildViewForm();
            SceneBuildLv build = form.View(selectLevel);
            if (build != null)
            {
                selectLevel = build;

                UpdatePictureBox();
            }
        }

        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            copyLevel = (SceneBuildLv)selectLevel.Clone();
            
        }

        private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SceneBuildLv s = (SceneBuildLv)copyLevel.Clone(); ;
            

            this.sceneMap.BuilList.Add(s);

            selectLevel = s;

            UpdatePictureBox();
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectLevel != null)
            {
                sceneMap.BuilList.Remove(selectLevel);
                selectLevel = null;
                UpdatePictureBox();
            }
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            this.ShowBuidBorder = checkBox4.Checked;
            UpdatePictureBox();
        }

        

        
    }
}
